'use strict';
const Service = require('egg').Service;

const Json2csvParser = require('json2csv').Parser;

class UserService extends Service {

  /*
    * 获取用户分页列表
    * */
  async pageList(condition, page = 1, order = []) {
    const { pageSize } = this.config.common;
    const offset = (page - 1) * pageSize;
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [['create_time', 'desc'], ['userid', 'desc']];
    this.ctx.model.User.hasOne(this.ctx.model.Userinfo, { foreignKey: 'id' });
    const attributes = Object.keys(this.ctx.model.User.attributes);
    attributes.push(...[
      [this.app.Sequelize.col('user_info.id'), 'id'],
      [this.app.Sequelize.col('user_info.mobile'), 'mobile'],
      [this.app.Sequelize.col('user_info.email'), 'email'],
      [this.app.Sequelize.col('user_info.realname'), 'realname'],
    ]);
    const results = await this.ctx.model.User.findAndCount({
      where: condition,
      attributes,
      order,
      limit: pageSize,
      offset,
      include: [
        { model: this.ctx.model.Userinfo, required: true, attributes: [] },
      ],
      raw: true,
    });
    return results;
  }

  /*
    * 获取用户列表
    * */
   async getList(condition, order = []) {
    if (!Object.keys(condition)) condition = { 1: 1 };
    if (!order.length) order = [['create_time', 'desc'], ['userid', 'desc']];
    this.ctx.model.User.hasOne(this.ctx.model.Userinfo, { foreignKey: 'id' });
    const attributes = Object.keys(this.ctx.model.User.attributes);
    attributes.push(...[
      [this.app.Sequelize.col('user_info.id'), 'id'],
      [this.app.Sequelize.col('user_info.mobile'), 'mobile'],
      [this.app.Sequelize.col('user_info.email'), 'email'],
      [this.app.Sequelize.col('user_info.realname'), 'realname'],
    ]);
    const results = await this.ctx.model.User.findAll({
      where: condition,
      attributes,
      order,
      include: [
        { model: this.ctx.model.Userinfo, required: true, attributes: [] },
      ],
      raw: true,
    });
    return results;
  }

  /* 获取用户信息*/
  async getUserInfo(condition) {
    if (!Object.keys(condition)) return {};
    this.ctx.model.User.hasOne(this.ctx.model.Userinfo, { foreignKey: 'id' });
    const attributes = Object.keys(this.ctx.model.User.attributes);
    attributes.push(...[
      [this.app.Sequelize.col('user_info.id'), 'id'],
      [this.app.Sequelize.col('user_info.mobile'), 'mobile'],
      [this.app.Sequelize.col('user_info.email'), 'email'],
      [this.app.Sequelize.col('user_info.realname'), 'realname'],
    ]);
    const results = await this.ctx.model.User.findOne({
      where: condition,
      attributes,
      include: [
        { model: this.ctx.model.Userinfo, required: true },
      ],
      raw: true,
    });
    return results;
  }

  /*
   * 用户活跃度统计 - 统计的区间
   * @param int|string|array times
   * @param int 类型：0-注册用户，1-最近登录用户
   * return int
   */
  async getUserCount(times, type = 0) {
    const { start_time, end_time } = this.ctx.helper.get_between_time(times);
    const condition = { delete_time: 0 };
    if (start_time && end_time) {
      if (type) {
        condition.login_time = { [this.app.Sequelize.Op.between]: [start_time, end_time] };
      } else {
        condition.create_time = { [this.app.Sequelize.Op.between]: [start_time, end_time] };
      }
    }
    const res = await this.ctx.model.User.count({ where: condition });
    return parseFloat(res) ? parseFloat(res) : 0;
  }

  /*
   * 用户活跃度统计 - 以天为单位进行统计
   * @param int|string|array times
   * @param int 类型：0-注册用户，1-最近登录用户
   * return int
   */
  async getUserByDay(times, type = 0) {
    const { start_time, end_time } = this.ctx.helper.get_between_time(times);
    const condition = { delete_time: 0 };
    if (start_time && end_time) {
      if (type) {
        condition.login_time = { [this.app.Sequelize.Op.between]: [ start_time, end_time ] };
      } else {
        condition.create_time = { [this.app.Sequelize.Op.between]: [ start_time, end_time ] };
      }
    }
    const attributes = Object.keys(this.ctx.model.User.attributes);
    const res = await this.ctx.model.User.findAll({
      where: condition, attributes: {
        include: [
          [ this.app.Sequelize.fn('FROM_UNIXTIME', this.app.Sequelize.col(type ? 'login_time' : 'create_time'), '%Y-%m-%d'), 'grap' ],
          [ this.app.Sequelize.fn('COUNT', this.app.Sequelize.col('userid')), 'total' ],
          // [this.app.Sequelize.fn('SUM', this.app.Sequelize.literal('`amount`*`fee`')), 'total_fee'],
        ],
        exclude: attributes,
      },
      raw: true, group: 'grap',
    });
    const data = new Map();
    if (res.length) {
      for (const item of res) {
        data.set(item.grap, item.total);
      }
    }
    return data;
  }

  /*
   * 添加用户
   * @param Object addData
   * return int
   */
  async addUser(addData, back = {}) {
    const ctx = this.ctx;
    let password = addData.password;
    const username = addData.username;
    const credit = parseInt(addData.credit) || 0;
    const qq = addData.qq || '';
    const email = addData.email || '';
    const mobile = addData.mobile || '';
    const realname = addData.realname || '';
    const status = parseInt(addData.status) || 0;
    password = ctx.helper.trim(password);
    if (!password || password.length < 6 || !ctx.helper.check_name(password)) {
      back.error = '密码为字母或数字，且长度不能低于6位';
      return false;
    }
    if (!username || !ctx.helper.check_name(username)) {
      back.error = '用户名为字母或数字';
      return false;
    }
    if (mobile && !ctx.helper.check_mobile(mobile)) {
      back.error = '手机号码格式错误';
      return false;
    }
    if (email && !ctx.helper.check_email(email)) {
      back.error = '邮箱格式错误';
      return false;
    }
    const create_time = ctx.helper.date_to_time();
    password = ctx.helper.md5(password);
    const userData = { username, password, credit, create_time, status };
    const userInfoData = { qq, email, mobile, realname };
    const t = await this.app.model.transaction();
    try {
      const userRes = await this.ctx.model.User.create(userData, { raw: true, transaction: t });
      if (userRes && userRes.userid) {
        userInfoData.id = userRes.userid;
      }
      const userInfoRes = await this.ctx.model.Userinfo.create(userInfoData, { raw: true, transaction: t });
      if (userRes && userInfoRes) {
        t.commit();
        await this.ctx.service.admin.recordDbLog('添加用户', this.ctx.model.User.getTableName('tableName'), { data: { userData, userInfoData } });
        return true;
      }
      t.rollback();
      await this.ctx.service.admin.rocordErrLog('用户添加失败');
      return false;
    } catch (e) {
      t.rollback();
      await this.ctx.service.admin.rocordErrLog('用户添加失败');
      return false;
    }
  }

  downloadUserInfo(data) {
    const fields = [ 'id', 'username', 'credit', 'mobile', 'qq', 'emaile', 'realname', 'create_date', 'login_date', 'status' ];
    const opt = { fields };
    const content = [];
    for (const user of data) {
      const item = {};
      item.id = user.userid;
      item.username = user.username;
      item.credit = user.credit;
      item.mobile = user.mobile;
      item.qq = user.qq;
      item.emaile = user.emaile;
      item.realname = user.realname;
      item.status = user.status == 1 ? '正常' : '冻结';
      item.create_date = this.ctx.helper.time_to_date(user.create_time, 5);
      item.login_date = this.ctx.helper.time_to_date(user.login_time, 5);
      content.push(item);
    }
    const json2csvp = new Json2csvParser(opt);
    const csv = json2csvp.parse(content);
    return csv;
  }

}

module.exports = UserService;
